package vn.mahjonggame.platform;

import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;

import vn.mahjonggame.game.MahjongExtension;
import vn.mahjonggame.metadata.ConfigObject;
import vn.mahjonggame.util.PropertiesCache;
import vn.mahjonggame.util.RandomString;

import com.smartfoxserver.v2.entities.data.SFSArray;
import com.smartfoxserver.v2.entities.data.SFSObject;

public class PlatformClient {
		
	public static final boolean isDebug = (PlatformConfig.configMap.get(PlatformConfig.SERVER_MODE).equalsIgnoreCase(ServerMode.DEBUG.toString()) ? true : false);
	
	/*
	 * @param token
	 */
	public static synchronized SFSObject get_access_token(String token){		
		SFSObject response = null;
		
		if(!isDebug){
			String uri = "/oauth/get_access_token";		
			String query = String.format("?token=%s", token);
			response = sendHttpRequest("GET", uri+query, "");
		}
		
		return response;		
	}
	
	/***	 
	 * @param access_token
	 * @return
	 */
	public static synchronized SFSObject user_get_info(String access_token) {		
		SFSObject response = null;
		if(!isDebug){
			String uri = "/user/get_info";
			String query = String.format("?access_token=%s", access_token);
			response = sendHttpRequest("GET", uri+query, "");
		}
		else {
			response = getSFSObject();
			
			RandomString randomUserId = new RandomString(24);
			RandomString randomDisplayName = new RandomString(4);
			SFSObject data = new SFSObject();
			data.putUtfString("user_id", randomUserId.nextString());
			data.putUtfString("displayname", "Guest_" + randomDisplayName.nextString());
			Calendar cal = Calendar.getInstance();
			cal.add(Calendar.YEAR, -20);
			data.putUtfString("birthday", String.valueOf(cal.getTime()));
			data.putUtfString("gender", "Male");
			
			response.putSFSObject("response", data);
		}			
		return response;
	}
		
	/**
	 * @param access_token
	 * @return
	 */
	public static synchronized SFSObject user_get_balance(String access_token) {
		SFSObject response = null;
		if(!isDebug){
			String uri = "/user/get_balance";
			String query = String.format("?access_token=%s", access_token);
			response = sendHttpRequest("GET", uri+query, "");
		}
		else{
			response = getSFSObject();
			
			SFSObject data = new SFSObject();
			data.putDouble("balance", Double.valueOf(PlatformConfig.configMap.get(PlatformConfig.TUTORIAL_BALANCE)));
			
			response.putSFSObject("response", data);
		}
				
		return response;
	}
	

	/***	
	 * @param access_token
	 * @param room_name 
	 * @param default_bet
	 * @param spend_money
	 * @return
	 */
	public static synchronized SFSObject game_create_room(String access_token, String room_name, int default_bet, int spend_money) {
		SFSObject response = null;
		
		if(!isDebug){
			String uri = "/game/create_room";
			String query = String.format("?access_token=%s", access_token);		
			
			SFSObject body = new SFSObject();
			body.putUtfString("room_name", room_name);
			
			SFSObject roomConfig = new SFSObject();			
			roomConfig.putDouble("default_bet", default_bet);			
			roomConfig.putDouble("spend_money", spend_money);
			
			body.putSFSObject("room_configs", roomConfig);
			
			response = sendHttpRequest("POST", uri+query, body.toJson());
		}
		else {
			response = getSFSObject();
			RandomString room_id_str = new RandomString(24);
			RandomString transaction_id_str = new RandomString(32);
			
			SFSObject data = new SFSObject();
			data.putUtfString("room_id", room_id_str.nextString());
			data.putUtfString("transaction_id", transaction_id_str.nextString());
			
			response.putSFSObject("respone", data);
		}
		
		return response;
	}	
		
	/***	 
	 * @param access_token
	 * @param platform_room_id
	 * @return
	 */
	public static synchronized SFSObject game_start_room(String access_token, String room_id, SFSArray players)
	{
		SFSObject response = null;
		
		if(!isDebug){
			String uri = "/game/start_room2";
			String query = String.format("?access_token=%s", access_token);
			
			/*
			 * Body JSON
			 */
			SFSObject body = new SFSObject();
			body.putUtfString("room_id", room_id);
			body.putSFSArray("players", players);		
			
			response = sendHttpRequest("POST", uri+query, body.toJson());
		}
		else {
			response = getSFSObject();
			SFSObject data = new SFSObject();
			data.putBool("status", true);
			data.putInt("player_ok", 4);
			data.putInt("player_error", 0);
			
			SFSObject players_status = new SFSObject();
			for(int i = 0; i < players.size(); i++){										
				players_status.putBool(String.valueOf(players.get(i)), true);				
			}			
			data.putSFSObject("players", players_status);
			data.putSFSArray("error_results", new SFSArray());
			
			response.putSFSObject("response", data);
		}		
				
		return response;
	}
	
	public static synchronized SFSObject logs_write(String access_token, String room_id, SFSArray actions)
	{
		SFSObject response = null;
		
		if(!isDebug){
			String uri = "/logs/write";
			String query = String.format("?access_token=%s", access_token);
			
			SFSObject body = new SFSObject();
			body.putUtfString("room_id", room_id);
			body.putUtfString("log_type", "game_logs");
			body.putSFSArray("log_data", actions);
			
			response = sendHttpRequest("POST", uri+query, body.toJson());
		}
		else {
			response = getSFSObject();
			SFSObject data = new SFSObject();
			data.putBool("status", true);
			response.putSFSObject("response", data);
		}
		
		return response;
	}
	
	public static synchronized SFSObject getSFSObject() {
		SFSObject sFSObject = new SFSObject();
		sFSObject.putUtfString("msgText", "Debug version");
		sFSObject.putBool("status", true);
		sFSObject.putInt("returnCode", 200);
		sFSObject.putUtfString("dateTime", String.valueOf(Calendar.getInstance().getTime()));
		
		return sFSObject;
	}	
	
	private static synchronized SFSObject sendHttpRequest(String method, String uri, String postData) {

		String url = PlatformConfig.configMap.get(PlatformConfig.PLATFORM_URL) + uri;

		String responseJson = "";
		try {
			URL obj = new URL(url);
			HttpURLConnection con = (HttpURLConnection) obj.openConnection();

			// optional default is GET
			con.setRequestMethod(method);
				
			// add request header
			con.setRequestProperty("User-Agent", "SFS2X");
			con.setRequestProperty("Content-Type", "application/json");
			con.setRequestProperty("Accept-Charset", "UTF-8");

			con.setRequestProperty("x-game-id", PlatformConfig.configMap.get(PlatformConfig.X_GAME_ID));
			con.setRequestProperty("x-secret-key", PlatformConfig.configMap.get(PlatformConfig.X_SECRET_KEY));
			
			if ( method.equals("POST")){
				// Send post request
				con.setDoOutput(true);
				DataOutputStream wr = new DataOutputStream(con.getOutputStream());
				wr.write(postData.getBytes("UTF-8"));
				wr.flush();
				wr.close();
			}

			int responseCode = con.getResponseCode();
			
			//trace("Sending '"+method+"' request to URL : " + url);
			//if (postData != null && postData.length() > 0)
				//log.info("Post Data: " + postData);
			//log.info("Response Code : " + responseCode);

			BufferedReader in = new BufferedReader(new InputStreamReader(
					con.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null) {
				response.append(inputLine);
			}
			in.close();

			//log.info("RESPONSE: " + response.toString());
			
			responseJson = response.toString();
			
		} catch (Throwable t) 
		{
			//log.error("Failed in sendHttpRequest : ", t);
		}
		
		// print result
		if (responseJson == ""){
			return null;
		}
		SFSObject sfsResponse = (SFSObject) SFSObject.newFromJsonData(responseJson);		
		return sfsResponse;
	}	
	
}
